home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / Hack / UTILS / WPCRACKA.ZIP / WPUNCRYP.C < prev    next >
C/C++ Source or Header  |  1996-03-03  |  8KB  |  315 lines

  1.  
  2. /*----------------------------------------------------------------------
  3. **  WPUNCRPY - Copyright (c) 1990, 91 Ron Dippold 10/11/91
  4. **  rdippold@qualcomm.com
  5. **
  6. **  Attempt to decrypt a Word Perfect file once you know the password.
  7. **  This is just so that Word Perfect isn't needed.
  8. **
  9. **  This source code is hereby released for public use.  All I ask is
  10. **  that if you make some cool new additions or enhancements that you
  11. **  mail me the update.  And if you use the program or source code,
  12. **  give me a little credit.
  13. **
  14. **  I'm not claiming this is the best code you've ever seen, it's just
  15. **  a fast hack, but it works.  I tried to be generic as possible so
  16. **  that it will compile on almost any platform.  It was written under
  17. **  Borland C.
  18. **----------------------------------------------------------------------*/
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. FILE *fin, *fout;
  24. char *inname, *outname, *pass;
  25.  
  26. typedef unsigned char byte;
  27. typedef unsigned int  word;
  28.  
  29. word ver5 = 0;                                /* version 4 or 5 */
  30. word override = 0;            /* override checksum */
  31. word pause = 0;               /* pause on screen */
  32. word text = 0;                /* text mode */
  33. word soft = 0;                /* translate CR as a space in text mode */
  34.  
  35. long tstart;                                    /* start of text position */
  36. long pos;                     /* position in file */
  37. word lines, chars;            /* lines of text */
  38.  
  39. word plen;                    /* password length */
  40. word csum, csum1;             /* checksum */
  41.  
  42. word len;                     /* bytes to read */
  43. word idx;                     /* index into buffer */
  44.  
  45. byte buf[4096], c;
  46.  
  47. word pidx;                    /* index down password */
  48. byte xmask;                   /* XOR mask */
  49.  
  50. int i, j, k;
  51.  
  52. void docs() {
  53.     printf( " To uncrypt a Word Perfect 4.x or 5.x file, the syntax is:\n\n");
  54.     printf("    WPUNCRYP (-o) (-p) (-b) w|t \"password\" <input file> (<output file>) \n\n");
  55.     printf("  Use the 'w' command to decrypt <input file> into <output file>\n");
  56.     printf("    in Word Perfect format.  This option is meaningless if <output\n");
  57.     printf("    file> is not given.\n");
  58.     printf("  Use the 't' command to decrypt the text portion of <input file>.\n");
  59.     printf("    This will not remove any embedded formatting codes, you can do\n");
  60.     printf("    that yourself!\n");
  61.     printf(" If <output file> is not given, the decrypted text will be shown to\n");
  62.     printf("    the screen.\n");
  63.     printf(" The optional -o switch will force the decrpytion even if the checksum\n");
  64.     printf("    of the password doesn't match the checksum of the file.\n");
  65.     printf(" The optional -p switch will make the make WPUNCRYP attempt to pause\n");
  66.     printf("    after every screen of output to the screen.\n");
  67.   printf(" In text output mode, both hard and soft line breaks are output as a\n");
  68.   printf("    CR/LF.  The optional -b will translate the soft break as a space.\n");
  69.     exit(1);
  70. }
  71.  
  72. void main( int argc, char **argv )
  73. {
  74.     printf( "\nWPUNCRYP 1.0 - Copyright (c) 1990,91 Ron Dippold\n\n" );
  75.  
  76.     if( argc <4 || argc > 7 ) {
  77.         docs();
  78.     }
  79.  
  80.     i=1;
  81.   override = pause = text = soft = 0;
  82.  
  83.     while( i<argc && argv[i][0] == '-' ) {
  84.     switch( argv[i][1] ) {
  85.       case 'o':
  86.       case 'O':
  87.               override = 1;
  88.         break;
  89.       case 'p':
  90.       case 'P':
  91.                 pause = 1;
  92.         break;
  93.       case 'b':
  94.       case 'B':
  95.         soft = 1;
  96.         break;
  97.       default:
  98.                 docs();
  99.         }
  100.         i++;
  101.     }
  102.  
  103.     if( i>= argc-2 ) {
  104.         docs();
  105.     }
  106.  
  107.   if( argv[i][1]!='\0' ) docs();
  108.   if( argv[i][0]=='t' ) {
  109.     text = 1;
  110.   } else {
  111.         if( argv[i][0]=='w' ) {
  112.       text = 0;
  113.         } else {
  114.       docs();
  115.     }
  116.     }
  117.   i++;
  118.  
  119.     pass = argv[i++];
  120.   plen = strlen( pass );
  121.  
  122.   inname = argv[i++];
  123.  
  124.   if( i< argc ) {
  125.         outname = argv[i];
  126.         pause = 0;
  127.     } else {
  128.         outname = NULL;
  129.         text = 1;
  130.     }
  131.  
  132.     if( i > argc ) {
  133.         docs();
  134.     }
  135.  
  136.   if( !text ) {
  137.     soft = 0;
  138.   }
  139.  
  140.  
  141.     if( !( fin = fopen( inname, "rb" ))) {
  142.         printf( "  Could not open file %s\n", inname );
  143.         exit( 2 );
  144.     }
  145.  
  146.     fseek( fin, 0L, SEEK_SET );
  147.     if( fread( buf, 1, 4, fin ) != 4) {
  148.         fclose( fin );
  149.         printf( "  Couldn't read 4 bytes from file %s!\n", inname );
  150.         exit( 3 );
  151.     }
  152.  
  153.     if( buf[0]==0xff && buf[1]==0x57 && buf[2]==0x50 && buf[3]==0x43 ) {
  154.         printf( "  This is a Word Perfect 5.x file.\n");
  155.         ver5 = 1;
  156.     } else {
  157.         if( buf[0]==0xfe && buf[1]==0xff && buf[2]==0x61 && buf[3]==0x61 ) {
  158.             printf( " This is a Word Perfect 4.1 encrypted file.\n");
  159.         } else {
  160.             fclose( fin );
  161.             printf( "  The identification bytes in this file are not those of a\n" );
  162.             printf( "  Word Perfect 5.x or 4.x encrpyted file.\n" );
  163.             exit( 4 );
  164.         }
  165.     }
  166.  
  167.   if( ver5 ) {
  168.       if( fread( &buf[4], 1, 12, fin ) != 12 ) {
  169.           fclose( fin );
  170.             printf( "  Couldn't read the first 16 bytes of the file - garbaged!\n" );
  171.           exit( 5 );
  172.       }
  173.  
  174.         if( buf[12]==0 && buf[13]==0 ) {
  175.             printf( "  The file claims it is not encrypted.\n" );
  176.             fclose( fin ); exit( 6 );
  177.       }
  178.     }
  179.  
  180.   /* Now read the checksum */
  181.   if( ver5 ) {
  182.         csum1 = (buf[12]<<8) + buf[13];
  183.     } else {
  184.       if( fread( &buf, 1, 2, fin ) != 2) {
  185.       printf( "  Couldn't read checksum - short file!\n");
  186.             fclose( fin ); exit( 7 );
  187.     }
  188.         csum1 = (buf[4]<<8) + buf[5];
  189.   }
  190.  
  191.   csum = 0;
  192.   for( i=0; i<plen; i++ ) {
  193.     if( pass[i]>='a' && pass[i]<='z') {   /* convert to upper case */
  194.             pass[i] -= 'a'-'A';
  195.         }
  196.         csum = ( (csum >> 1) | ( csum << 15) ) ^ ( pass[i]<<8 );
  197.     }
  198.  
  199.     if( csum != csum1 ) {
  200.         if( override ) {
  201.             printf( "  Warning!  Password checksum does not match file checksum!\n");
  202.             printf( "  Any output is suspect.\n");
  203.         } else {
  204.             printf( "  The password checksum does not match the checksum in the file.\n");
  205.             printf( "  If you are convinced it is right, check the docs for the -o option.\n");
  206.             fclose( fin ); exit( 8 );
  207.         }
  208.     }
  209.  
  210.     /* get start of text */
  211.     if( ver5) {
  212.         tstart = *((long *) (&buf[4]));
  213.     pos = 16;
  214.     } else {
  215.         tstart = pos = 6;
  216.     }
  217.  
  218.     if( outname ) {
  219.         if( !( fout = fopen( outname, text ? "wt":"wb" ))) {
  220.             printf( "  Could not open file %s\n", outname );
  221.             exit( 2 );
  222.         }
  223.       fseek( fout, 0L, SEEK_SET );
  224.     } else {
  225.         fout = NULL;
  226.     }
  227.  
  228.     if( ver5 && fout && !text ) {
  229.         buf[12] = buf[13] = 0;        /* write out first part of WP5.1 file */
  230.         fwrite( &buf[0], 1, 16, fout );
  231.     }
  232.  
  233.     pidx = 0;                       /* start of password */
  234.     xmask = plen+1;                 /* start at password length+1 */
  235.  
  236.     if( ver5 ) {                    /* get rid of printer info, etc. */
  237.         while( pos<tstart ) {
  238.             if( tstart-pos > 4096 ) {
  239.                 len = 4096;
  240.             } else {
  241.                 len = tstart-pos;
  242.             }
  243.             if( fread( buf, 1, len, fin ) !=len ) {
  244.                 printf( "\n  Unexpected end of file for %s.\n", inname );
  245.                 fclose( fin ); fclose( fout ); exit( 20 );
  246.             }
  247.             for( idx=0; idx<len; idx++ ) {      /* now decrypt */
  248.                 buf[idx] ^= pass[pidx++] ^ xmask++;
  249.                 if( pidx == plen ) pidx = 0;
  250.             }
  251.             if( fout && !text ) {
  252.                 if( fwrite( buf, 1, len, fout ) !=len ) {
  253.                     printf( "\n  Couldn't write %d bytes to %s.\n", len, outname );
  254.                     fclose( fin ); fclose( fout ); exit( 20 );
  255.                 }
  256.             }
  257.             pos += len;
  258.         } /* while */
  259.     } /* ver5 */
  260.  
  261.     idx = len = 0;                  /* no data yet */
  262.     lines = chars = 0;              /* no lines shown */
  263.  
  264.     do {
  265.  
  266.         /* read from file as necessary */
  267.         if( idx>=len ) {
  268.             if( len>0 && fout ) {
  269.                 if( fwrite( buf, 1, len, fout ) !=len ) {
  270.                     printf( "\n  Couldn't write %d bytes to %s.\n", len, outname );
  271.                     fclose( fin ); fclose( fout ); exit( 20 );
  272.                 }
  273.             }
  274.             len = fread( buf, 1, 4096, fin );
  275.             pos += len;
  276.             if( len == 0 ) {
  277.                 break;                    /* all done with file */
  278.             }
  279.             idx = 0;
  280.         }
  281.  
  282.         c = buf[idx] ^= pass[pidx++] ^ xmask++;
  283.         if( pidx == plen ) pidx = 0;
  284.  
  285.         if( text ) {
  286.             if( c == 0xA9 ) buf[idx] = '-'; /* translate annoying dashes */
  287.             if( c == 0x0D ) {           /* handle soft break */
  288.                 if( soft ) {
  289.                     buf[idx] = ' ';
  290.                 } else {
  291.                     buf[idx] = '\n';
  292.                 }
  293.             }
  294.         }
  295.  
  296.  
  297.         if( !fout ) {
  298.             printf( "%c",c = buf[idx] );
  299.             if( c == '\n' || ++chars == 80) {
  300.                 lines++; chars=0;
  301.                 if( lines == 24 && pause) {
  302.                     getch();
  303.                     lines = 0;
  304.                 }
  305.             }
  306.         }
  307.  
  308.         idx++;
  309.  
  310.     } while( 1 );
  311.  
  312.     fclose( fin );
  313.     if( fout) fclose( fout );
  314. }
  315.